﻿Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Globalization
Imports System.Reflection
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Compiler

Namespace System.Workflow.ComponentModel.Design
    <ActivityDesignerTheme(GetType(InvokeWorkflowDesignerTheme))> _
    Friend NotInheritable Class InvokeWorkflowDesigner
        Inherits ActivityHostDesigner
        ' Methods
        Protected Overrides Sub Initialize(ByVal activity As Activity)
            MyBase.Initialize(activity)
            Me.HelpText = DR.GetString("SpecifyTargetWorkflow", New Object(0  - 1) {})
            Me.RefreshTargetWorkflowType
        End Sub

        Protected Overrides Sub OnActivityChanged(ByVal e As ActivityChangedEventArgs)
            MyBase.OnActivityChanged(e)
            If ((Not e.Member Is Nothing) AndAlso String.Equals(e.Member.Name, "TargetWorkflow", StringComparison.Ordinal)) Then
                If ((Not e.OldValue Is e.NewValue) AndAlso (Not MyBase.Activity Is Nothing)) Then
                    Dim property As PropertyInfo = MyBase.Activity.GetType.GetProperty("ParameterBindings", (BindingFlags.Public Or BindingFlags.Instance))
                    If (Not [property] Is Nothing) Then
                        Dim bindings As WorkflowParameterBindingCollection = [TryCast]([property].GetValue(MyBase.Activity, Nothing),WorkflowParameterBindingCollection)
                        If (Not bindings Is Nothing) Then
                            bindings.Clear
                        End If
                    End If
                End If
                Me.RefreshTargetWorkflowType
            End If
        End Sub

        Protected Overrides Sub PreFilterProperties(ByVal properties As IDictionary)
            MyBase.PreFilterProperties(properties)
            If (Not Me.targetWorkflowType Is Nothing) Then
                Try 
                    Dim info As PropertyInfo
                    For Each info In Me.targetWorkflowType.GetProperties
                        If (((info.CanWrite AndAlso (Not info.DeclaringType Is GetType(DependencyObject))) AndAlso ((Not info.DeclaringType Is GetType(Activity)) AndAlso (Not info.DeclaringType Is GetType(CompositeActivity)))) AndAlso (((Not info.DeclaringType Is Type.GetType("System.Workflow.Activities.SequentialWorkflowActivity, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")) AndAlso (Not info.DeclaringType Is Type.GetType("System.Workflow.Activities.StateMachineWorkflowActivity, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"))) OrElse Not String.Equals(info.Name, "DynamicUpdateCondition", StringComparison.Ordinal))) Then
                            Dim flag As Boolean = False
                            Dim targetWorkflowType As Type = Me.targetWorkflowType
                            Do While ((Not targetWorkflowType Is Nothing) AndAlso TypeOf targetWorkflowType Is DesignTimeType)
                                targetWorkflowType = targetWorkflowType.BaseType
                            Loop
                            If (Not targetWorkflowType Is Nothing) Then
                                Dim property As DependencyProperty
                                For Each property In DependencyProperty.FromType(targetWorkflowType)
                                    If (([property].Name = info.Name) AndAlso [property].DefaultMetadata.IsMetaProperty) Then
                                        flag = True
                                        Exit For
                                    End If
                                Next
                            End If
                            If Not flag Then
                                Dim descriptor As PropertyDescriptor = New ParameterInfoBasedPropertyDescriptor(Type.GetType("System.Workflow.Activities.InvokeWorkflowActivity, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"), info.Name, info.PropertyType, InvokeWorkflowDesigner.ReservedParameterNames.Contains(info.Name), New Attribute() { DesignOnlyAttribute.Yes })
                                properties.Item(descriptor.Name) = descriptor
                            End If
                        End If
                    Next
                Catch exception1 As MissingMemberException
                End Try
            End If
        End Sub

        Friend Sub RefreshTargetWorkflowType()
            If (Not MyBase.Activity Is Nothing) Then
                Dim activity As ITypeFilterProvider = [TryCast](MyBase.Activity,ITypeFilterProvider)
                Dim type As Type = [TryCast](MyBase.Activity.GetType.InvokeMember("TargetWorkflow", (BindingFlags.ExactBinding Or (BindingFlags.GetProperty Or (BindingFlags.FlattenHierarchy Or (BindingFlags.Public Or (BindingFlags.Instance Or BindingFlags.DeclaredOnly))))), Nothing, MyBase.Activity, New Object(0  - 1) {}, CultureInfo.InvariantCulture),Type)
                If ((Not type Is Nothing) AndAlso activity.CanFilterType(type, False)) Then
                    Dim service As ITypeProvider = DirectCast(MyBase.GetService(GetType(ITypeProvider)), ITypeProvider)
                    If (Not service Is Nothing) Then
                        Dim type2 As Type = Nothing
                        If ((type.Assembly Is Nothing) AndAlso (Not service.LocalAssembly Is Nothing)) Then
                            type2 = service.LocalAssembly.GetType(type.FullName)
                        Else
                            type2 = service.GetType(type.FullName)
                        End If
                        If (Not type2 Is Nothing) Then
                            type = type2
                        End If
                    End If
                Else
                    type = Nothing
                End If
                If (Not Me.targetWorkflowType Is type) Then
                    Me.targetWorkflowType = type
                    MyBase.RefreshHostedActivity
                    If TypeOf Me.targetWorkflowType Is DesignTimeType Then
                        Me.HelpText = DR.GetString("BuildTargetWorkflow", New Object(0  - 1) {})
                    Else
                        Me.HelpText = DR.GetString("SpecifyTargetWorkflow", New Object(0  - 1) {})
                    End If
                End If
                TypeDescriptor.Refresh(MyBase.Activity)
            End If
        End Sub


        ' Properties
        Protected Overrides ReadOnly Property RootActivity As Activity
            Get
                If ((Not Me.targetWorkflowType Is Nothing) AndAlso Not TypeOf Me.targetWorkflowType Is DesignTimeType) Then
                    Return [TryCast](Activator.CreateInstance(Me.targetWorkflowType),Activity)
                End If
                Return Nothing
            End Get
        End Property


        ' Fields
        Friend Const InvokeWorkflowRef As String = "System.Workflow.Activities.InvokeWorkflowActivity, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        Private Shared ReadOnly ReservedParameterNames As ArrayList = New ArrayList(New String() { "Name", "Enabled", "Description", "TargetWorkflow", "Invoking", "ParameterBindings" })
        Private targetWorkflowType As Type
    End Class
End Namespace

